<?php
namespace app\shop\library\coupon;

use cubox\Cubox;
use app\shop\library\ApiController;

/**
 * 优惠券库存
 * 
 * 用于优惠券库存管理
 */

class CouponStock{
    const LOCK_KEY = 'shop-coupon-lock:';
    const NUM_KEY = 'shop-coupon-num:';
    public static function lock($coupon_id){
        $shop = Cubox::app('shop');
        $cache = $shop->cache();
        $lockKey = self::LOCK_KEY.$coupon_id;
        $lockTryNum = 100;
        while ($lockTryNum>0){

            if ($cache->setnx($lockKey,1)){
                $cache->expire($lockKey,10);
                return true;
            }
            usleep(100);
            $lockTryNum --;
        }
        return false;
    }

    public static function unlock($coupon_id){
        $shop = Cubox::app('shop');
        $cache = $shop->cache();
        $lockKey = self::LOCK_KEY.$coupon_id;
        $cache->del($lockKey);
    }


    //扣除 优惠券数量
    public static function reduce($coupon_id,$num=1){
        $shop = Cubox::app('shop');
        $cache = $shop->cache();

        $key = self::NUM_KEY.$coupon_id;

        if ($cache->exists($key)){
            $sum = $cache->get($key);
        }else{
            $sum = self::updateCouponNum($coupon_id);
            $cache->set($key,$sum);
        }

        if ($sum < $num){
            return false;
        }

        $cache->decr($key,$num);
        return true;
    }

    //恢复优惠券数量
    public static function recovery($coupon_id,$num=1){
        $shop = Cubox::app('shop');
        $cache = $shop->cache();

        $key = self::NUM_KEY.$coupon_id;

        if ($cache->exists($key)){
            $cache->incr($key,$num);
        }
    }

    public static function  updateCouponNum($coupon_id){

        $shop = Cubox::app('shop');
        $coupon = $shop->model('Coupon');
        $couponData = $coupon->getId($coupon_id);

        if ($couponData['stock'] == 0) return 0;

        $stockAt = $couponData['stock_at']??0;

        $receiveNum = $shop->model('MemberCoupon')->where('created_at','>',$stockAt)->where('coupon_id',$coupon_id)->count();

        if ($receiveNum > 0){
            $num = $couponData['stock']-$receiveNum;
        
            $update = [
                'stock' => $num,
                'stock_at' =>date('Y-m-d H:i:s')
            ];

            $coupon->updateId($coupon_id,$update);
        }else{
            $num = $couponData['stock'];
        }
        
        return $num;
    }
}